package com.springcloud.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springcloud.auth.config.OauthConfig;
import com.springcloud.auth.entity.TToken;
import com.springcloud.auth.mapper.TTokenMapper;
import com.springcloud.auth.service.TTokenService;
import com.springcloud.auth.utils.OauthUtils;
import com.springcloud.auth.utils.TokenUtil;
import com.springcloud.auth.vo.TokenVo;
import com.springcloud.commom.api.R;
import com.springcloud.commom.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hzl
 * @since 2019-12-09
 */
@Service
@Transactional
public class TTokenServiceImpl extends ServiceImpl<TTokenMapper, TToken> implements TTokenService {

    @Autowired
    private TTokenMapper mapper;

    @Autowired
    private RedisUtil redis;

    @Override
    public void clearToken(String accessToken) {

        QueryWrapper<TToken> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TToken::getAccessToken, accessToken);

        TToken tokenInfo = mapper.selectOne(queryWrapper);

        if (tokenInfo != null) {

            // 删除redis 记录
            redis.del(OauthConfig.AUTH_ACCESS_TOKEN + tokenInfo.getAccessToken());
            redis.del(OauthConfig.AUTH_REFRESH_TOKEN + tokenInfo.getRefreshToken());

            // 删除数据库中的记录
            mapper.deleteById(tokenInfo.getId());
        }
    }

    @Override
    public R<TokenVo> refreshAccessToken(String refreshToken) throws Exception {
        if (StringUtils.isBlank(refreshToken)) {
            return R.fail("refreshToken 为null!");
        }

        TokenVo vo;

        String token = OauthUtils.getRedisTokenByReToken(refreshToken);
        if (StringUtils.isNoneBlank(token)) {
            //删除旧的token凭证
            redis.del(OauthConfig.AUTH_REFRESH_TOKEN + refreshToken);

            //解析旧的reToken,拿到userId
            // 解析Token
            String userId = OauthUtils.getUserId(token);

            // 生成Token
            OAuthIssuer oauthIssuer = OauthUtils.createTokenInfo();

            String newRefreshToken = oauthIssuer.refreshToken();
            String newAccessToken = oauthIssuer.accessToken();

            // 生成TonkenEntity
            String newToken = TokenUtil.createToken(userId, newAccessToken, newRefreshToken);
            OauthUtils.saveRedisToken(newAccessToken, newRefreshToken, newToken);

            vo = new TokenVo();
            vo.setAcToken(newAccessToken);
            vo.setReToken(newRefreshToken);


            //更新数据库中的token
            QueryWrapper<TToken> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(TToken::getRefreshToken, refreshToken);

            TToken tokenInfo = mapper.selectOne(queryWrapper);
            if (tokenInfo != null) {
                Date now = new Date();

                tokenInfo.setAccessToken(newAccessToken);
                tokenInfo.setRefreshToken(newRefreshToken);
                tokenInfo.setAccessUpdateTime(now);
                tokenInfo.setRefreshUpdateTime(now);

                mapper.updateById(tokenInfo);
            }

            return R.data(vo);
        } else {
            return R.fail("refreshToken 无效!");
        }
    }

    @Override
    public void updateRefreshTime(String accessToken) {
        QueryWrapper<TToken> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TToken::getRefreshToken, accessToken);

        TToken tokenInfo = mapper.selectOne(queryWrapper);
        if (tokenInfo == null) {
            return;
        }
        tokenInfo.setRefreshUpdateTime(new Date());

        mapper.updateById(tokenInfo);
    }

}
